<template>
  <div id="bookMarksSync">
    <el-card id="header">
      <el-row style="padding: 5px 15px" tyge="flex">
        <el-col :span="12"  style="float: left;">
          <el-button type="text" id="btnDownload" @click="download">下载书签</el-button>
          <el-divider direction="vertical"></el-divider>
          <el-button type="text" id="btnUpload" @click="upload">上传书签</el-button>
        </el-col>
        <el-col :span="12" style="text-align: right;font-size:20px;">
          <el-button type="text" circle id="btnShowConfig" @click="showConfigForm" icon="el-icon-setting"></el-button>
        </el-col>
      </el-row>
    </el-card>
    <div v-if="showConfig" style="margin-top: 20px;">
    <el-tabs type="border-card">
      <el-tab-pane label="gitee 配置" >
        <el-form :model="userConfigForm" :rules="rules" ref="userConfigForm" label-position="top-left" style="padding: 20px;height: 315px">
<!--          <el-form-item prop="username" label="用户名">-->
<!--            <el-input v-model="userConfigForm.username" placeholder="you username"></el-input>-->
<!--          </el-form-item>-->
<!--          <el-form-item prop="repo" label="仓库名">-->
<!--            <el-input v-model="userConfigForm.repo" placeholder="yuo repo name"></el-input>-->
<!--          </el-form-item>-->
          <el-form-item prop="url" label="文件url">
            <el-input v-model="userConfigForm.url" placeholder="you bookmark.json url"></el-input>
          </el-form-item>
          <el-form-item prop="token" label="token">
            <el-input v-model="userConfigForm.token" placeholder="you personal access tokens"></el-input>
          </el-form-item>
        </el-form>
        <div class="dialog-footer" style="padding:0 20px 20px 20px;height: 30px;">
          <el-button style="float: right;margin-left: 20px" type="primary" @click="saveUserConfig">保存</el-button>
          <el-button style="float: right;" type="danger" @click="clearUserConfig">清 除</el-button>
          <el-button style="float: right;" @click="showConfig = false">关 闭</el-button>
        </div>
      </el-tab-pane>
      <el-tab-pane label="其他配置" >
        <el-form :model="otherConfigForm" ref="otherConfigForm"
                 :rules="otherConfigRules"
                 label-position="top-left" style="padding: 20px;height: 315px">
          <el-form-item prop="autoAsync" label="自动同步">
            <el-radio-group v-model="otherConfigForm.autoAsync">
              <el-radio :label="true">开启</el-radio>
              <el-radio :label="false">关闭</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item prop="asyncType" label="同步方式">
            <el-radio-group v-model="otherConfigForm.asyncType">
              <el-radio :label="0">覆盖</el-radio>
              <el-radio :label="1">合并</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
        <div class="dialog-footer" style="padding:0 20px 20px 20px;height: 30px;">
          <el-button style="float: right;margin-left: 20px" type="primary" @click="saveOtherConfig">保存</el-button>
          <el-button style="float: right;" @click="showConfig = false">关 闭</el-button>
        </div>
      </el-tab-pane>
    </el-tabs>
    </div>
    <el-card style="width: 100%;margin-top: 20px" v-if="!showConfig" id="divBbookmarks">
      <div slot="header" style="font-size: 16px; font-weight: bold;">
        <span>我的书签</span>
        <el-tooltip placement="top" effect="light" content="添加分组" style="float: right; padding: 3px 0">
          <el-button type="text" icon="el-icon-plus" @click="addGroup()"></el-button>
        </el-tooltip>
      </div>
      <el-tabs v-if="bookmarksGroup.length>0" v-model="selectGroup" tab-position="left" style="height: 415px;"
               @tab-click="handleTabClick">
        <el-tab-pane v-for="(item,index) in bookmarksGroup" :key="index" :label="item.groupName" :name="item.groupName">
          <div slot="label">
            <span> {{ item.groupName }} </span>
            <el-tooltip slot="label" placement="right" effect="light" content="点击删除分组">
              <el-button style="margin-left: 10px" type="text" icon="el-icon-delete"
                         @click="deleteGroup(item)"></el-button>
            </el-tooltip>

          </div>
          <el-table :data="groupBookmarks" :show-header="false" size="mini" height="415px">
            <el-col slot="empty">
              <el-empty :image-size="150" description="还未添加任何书签"></el-empty>
            </el-col>
            <el-table-column prop="title" label="书签名称" show-overflow-tooltip>
              <template slot-scope="scope">
                <el-row style="line-height: 3">
                  <el-col style="width: 380px;overflow: hidden">
                    <el-link :underline="false" :href="scope.row.url" target="_blank">{{ scope.row.title }}</el-link>
                  </el-col>
                  <el-col style="float: right;width: 60px">
                    <el-tooltip placement="top" effect="light" content="编辑" style="float: right;margin-left: 10px">
                      <el-button type="text" icon="el-icon-edit" @click="editBookmark(scope.row)"></el-button>
                    </el-tooltip>
                    <el-tooltip placement="top" effect="light" content="删除" style="float: right;margin-left: 10px">
                      <el-button type="text" icon="el-icon-delete" @click="deleteBookmark(scope.row)"></el-button>
                    </el-tooltip>
                  </el-col>
                </el-row>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </el-card>


    <el-dialog id="editBookmark" title="编辑书签" :visible.sync="dialogVisible" width="90%">
      <el-form :model="bookmarkForm" :rules="bookmarkFormRules" ref="bookmarkForm" label-position="left"
               style="padding: 0 20px;">
        <el-form-item prop="group" label="分组">
          <el-select v-model="bookmarkForm.group" placeholder="请选择分组" style="width: 100%" allow-create filterable
                     value-key="groupId">
            <el-option
                v-for="item in bookmarksGroup"
                :key="item.groupId"
                :label="item.groupName"
                :value="item">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item prop="title" label="名称">
          <el-input v-model="bookmarkForm.title" placeholder="you bookmark title"></el-input>
        </el-form-item>
        <el-form-item prop="url" label="地址">
          <el-input v-model="bookmarkForm.url" placeholder="you bookmark url"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="saveBookmark">保存</el-button>
      </div>
    </el-dialog>

    <el-dialog id="addGroup" title="添加分组" :visible.sync="dialogFormVisible" width="90%">
      <el-form :model="tabsForm" ref="tabsForm" :rules="tabsFormRules" label-position="left">
        <el-form-item label="分组名称" prop="groupName">
          <el-input v-model="tabsForm.groupName" maxlength="5" show-word-limit autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="addTabs">确 定</el-button>
      </div>
    </el-dialog>

    <giteeController ref="giteeController"/>
  </div>
</template>

<script>
/* eslint-disable */
import giteeController from './components/GiteeController.vue'

export default {
  name: 'App',
  components: {
    giteeController
  },
  data() {
    return {
      gitee: null,
      opts: null,
      userConfigForm: {
        url: null,
        token: null
      },
      otherConfigForm: {
        autoAsync: false,
        asyncType: 1,
      },
      rules: {
        url: [
          {required: true, message: '请输入用户名', trigger: 'blur'}
        ],
        token: [
          {required: true, message: '请输入token', trigger: 'blur'}
        ]
      },
      dialogVisible: false,
      dialogFormVisible: false,
      tabsForm: {
        name: null
      },
      tabsFormRules: {
        groupName: [
          {required: true, message: '请输入分组名称', trigger: 'blur'}
        ]
      },
      bookmarkForm: {},
      otherConfigFrom: {
        autoAsync: false,
        asyncType: 0,
      },
      otherConfigRules: {
        autoAsync: [
          {required: true, message: '请选择是否自动上传', trigger: 'blur'}
        ],
        asyncType: [
          {required: true, message: '请选择上传方式', trigger: 'blur'}
        ]
      },
      bookmarkFormRules: {
        group: [
          {required: true, message: '请选择分组', trigger: 'blur'}
        ],
        title: [
          {required: true, message: '请输入书签名称', trigger: 'blur'}
        ],
        url: [
          {required: true, message: '请输入书签地址', trigger: 'blur'}
        ]
      },
      bookmarksGroup: [],
      bookmarksList: [],
      bookmarks: {},
      selectGroup: '未分组',
      groupBookmarks: [],
      autoAsync: null,
      asyncType: null,
      showConfig: false,

    }
  },
  created() {
    this.getUserInfo();
    this.getOtherInfo();
    this.getBookmarksList();

  },

  methods: {
    msg(title, message, type) {
      this.$notify({
        title: title || '通知',
        message: message,
        type: type,
      });
    },
    /**
     * 获取用户信息
     */
    getUserInfo() {
      chrome.storage.local.get(['url', 'token'], (obj) => {
        console.log(JSON.stringify(obj));
        if (obj.url) {
          this.userConfigForm = {...obj};
          if(this.getUSerConfig()) {
            this.showConfig = false;
            this.$refs.giteeController.init(this.opts.username, this.opts.token);
            this.download()
          }
        } else {
          this.showConfig = true;
        }
      });
    },
    getOtherInfo(){
       chrome.storage.local.get(['asyncType','autoAsync'], (obj) => {
         // console.log(JSON.stringify(obj));
         if (obj.asyncType!=null) {
           this.asyncType = obj.asyncType;
         }else {
           this.asyncType = 0;
         }
         if(this.opts!= null && obj.autoAsync!=null ){
           this.autoAsync = obj.autoAsync;
         }else {
           this.autoAsync = false;
         }
         this.otherConfigForm = {
           asyncType: this.asyncType,
           autoAsync: this.autoAsync
         };
       });
    },
    getBookmarksList() {
      chrome.storage.local.get(['bookmarksGroup', 'bookmarksList'], (items) => {
        this.bookmarksGroup = items.bookmarksGroup || [{groupName: '未分组', groupId: 0}];
        this.bookmarksList = items.bookmarksList || [];
        this.getGroupBookmarks()
      })
    },

    showConfigForm() {
      this.showConfig = !this.showConfig;
    },
    getUSerConfig() {
      const url = this.userConfigForm.url;
      // 正则表达式
      const regex = /^https:\/\/gitee\.com\/(?<username>[^/]+)\/(?<repo>[^/]+)\/(blob|row)\/[^/]+\/(?<path>.+)$/;
      // 使用 match() 方法
      const match = url.match(regex);
      // 检查是否匹配成功
      if (match && match.groups) {
        const { username, repo, path } = match.groups;
        this.opts = {
          username: username,
          repo: repo,
          path: path,
          token: this.userConfigForm.token
        };
        return true;

      } else {
        console.log('URL does not match the expected pattern.');
        return false;
      }
    },
    saveUserConfig() {
      this.$refs['userConfigForm'].validate(valid => {
        if (valid) {
          if (this.getUSerConfig()) {
            chrome.storage.local.set(this.userConfigForm, () => {
              this.$refs.giteeController.init(this.opts.username, this.opts.token);
              this.showConfig = false;
              this.msg('', 'Gitee仓库信息保存成功', 'success');
            });
          }
        } else {
          return false;
        }
      });
    },
    clearUserConfig() {
      this.$confirm('此操作会清空你的gitee配置信息，无法再进行数据同步, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 用户点击了确定按钮
        chrome.storage.local.set({url: null, token: null, autoAsync: false}, () => {
          this.opts = null;
          this.$refs['userConfigForm'].resetFields();
          this.showConfig = false
          this.autoAsync = false
        })
      }).catch(() => {
        // 用户点击了取消按钮
        console.log('取消删除gitee配置信息');
      });

    },
    saveOtherConfig(){
      this.$refs['otherConfigForm'].validate(valid => {
        if (valid) {
          if (this.opts == null && this.otherConfigForm.autoAsync) {
            this.msg('', '请先配置gitee仓库信息', 'warning');
            this.otherConfigForm.autoAsync = false;
            return false;
          }
          chrome.storage.local.set(this.otherConfigForm, () => {
            this.autoAsync = this.otherConfigForm.autoAsync;
            this.asyncType = this.otherConfigForm.asyncType;
            this.showConfig = false;
            this.msg('', '配置已保存', 'success');
            if(this.autoAsync){
              this.autoupload(this.autoAsync,this.asyncType);
            }
          });
        } else {
          return false;
        }
      });
    },

    async autoupload(autoAsync,asyncType) {
      if(autoAsync){
        const getFileInfoRes = await this.$refs.giteeController.getFileInfo(this.opts.repo, 'master', this.opts.path)
        if (getFileInfoRes && getFileInfoRes.sha) {
          if(asyncType === 1){
            const bookmarks = JSON.parse(this.$base64.decode(getFileInfoRes.content))
            // console.log("bookmarks:"+bookmarks);
            this.bookmarksGroup = this.mergeAndDeduplicate(this.bookmarksGroup,bookmarks.bookmarksGroup, 'groupName');
            this.bookmarksList = this.mergeAndDeduplicate(this.bookmarksList,bookmarks.bookmarksList, 'url');
          }
          // console.log("bookmarksGroup0000:"+this.bookmarksGroup);
          // console.log("bookmarksList0000:"+this.bookmarksList);
          const res = await this.$refs.giteeController.updateJsonFile(this.opts.repo, 'master', this.opts.path, 'update', {
            bookmarksGroup: this.bookmarksGroup,
            bookmarksList: this.bookmarksList
          }, getFileInfoRes.sha);
          if (res) {
            console.log('自动上传已完成');
          } else {
            this.msg('', '书签自动上传失败', 'error');
          }
        } else {
          this.msg('', this.opts.path + '文件不存在！', 'error');
        }
      }else{
        console.log('自动上传未开启');
      }

    },

    async upload() {
      if (this.opts == null) {
        this.showConfig = true;
        this.msg('', '请点击右侧设置按钮，先配置gitee仓库信息', 'warning');
        return;
      }
      const getFileInfoRes = await this.$refs.giteeController.getFileInfo(this.opts.repo, 'master', this.opts.path)
      if (getFileInfoRes && getFileInfoRes.sha) {
        if(this.asyncType === 1 && getFileInfoRes.content){
          const bookmarks = JSON.parse(this.$base64.decode(getFileInfoRes.content))
          // console.log("bookmarks:"+JSON.stringify(bookmarks));
          this.bookmarksGroup = this.mergeAndDeduplicate(this.bookmarksGroup,bookmarks.bookmarksGroup,'groupName');
          this.bookmarksList = this.mergeAndDeduplicate(this.bookmarksList,bookmarks.bookmarksList, 'url');
        }
        // console.log("bookmarksGroup1111:"+JSON.stringify(this.bookmarksGroup));
        // console.log("bookmarksList1111:"+JSON.stringify(this.bookmarksList));
        const res = await this.$refs.giteeController.updateJsonFile(this.opts.repo, 'master', this.opts.path, 'update', {
          bookmarksGroup: this.bookmarksGroup,
          bookmarksList: this.bookmarksList
        }, getFileInfoRes.sha);
        if (res) {
          this.msg('', '书签上传成功', 'success');
        } else {
          this.msg('', '书签上传失败', 'error');
        }
      } else {
        this.msg('', this.opts.path + '文件不存在！', 'error');
      }


    },

    async download() {
      if (this.opts == null) {
        this.showConfig = true;
        this.msg('', '请先配置gitee仓库信息', 'warning');
        return;
      }
      // 下载书签配置，并替换当前书签栏
      const bookmarks = await this.$refs.giteeController.getJsonFile(this.opts.repo, 'master', this.opts.path)
      if (bookmarks) {
        // console.log("bookmarks:"+JSON.stringify(bookmarks));
        this.msg('', '书签下载成功', 'success');
        if(this.asyncType === 1){
          bookmarks.bookmarksGroup = this.mergeAndDeduplicate(this.bookmarksGroup,bookmarks.bookmarksGroup,'groupName');
          bookmarks.bookmarksList = this.mergeAndDeduplicate(this.bookmarksList,bookmarks.bookmarksList,'url');
        }
        // console.log("bookmarks2222:"+JSON.stringify(bookmarks));
        if(bookmarks.bookmarksGroup && bookmarks.bookmarksList){
          chrome.storage.local.set(bookmarks, () => {
            this.bookmarksGroup = bookmarks.bookmarksGroup;
            this.bookmarksList = bookmarks.bookmarksList;
            this.getGroupBookmarks()

          });
        }

      } else {
        this.msg('', '书签下载失败', 'error');
      }

    },
    handleTabClick(tab, event) {
      // `tab`参数包含了被点击的标签的信息
      // `event`是鼠标事件对象
      // 根据被点击的标签页加载数据
      this.selectGroup = tab.name;
      this.getGroupBookmarks()

    },
    addTabs() {
      this.$refs['tabsForm'].validate(valid => {
        if (valid) {
          this.bookmarksGroup.push(this.tabsForm);
          this.selectGroup = this.tabsForm.groupName;
          this.dialogFormVisible = false;
          this.groupBookmarks = [];
          chrome.storage.local.set({bookmarksGroup: this.bookmarksGroup}, () => {
            console.log(this.tabsForm.groupName + '=>书签分组已添加')
            this.autoupload(this.autoAsync,this.asyncType)
          })
        }
      });
    },
    addGroup() {
      this.dialogFormVisible = true;
      this.tabsForm = {
        groupName: '',
        groupId: Date.now()
      }
    },
    deleteGroup(group) {
      if (group.groupName === '未分组') {
        this.msg('', '此书签分组不可删除！', 'warning');
        return;
      }
      this.groupBookmarks = this.bookmarksList.filter(item => item.group.groupName === group.groupName)
      if (this.groupBookmarks.length > 0) {
        this.msg('', '请先删除分组下的书签', 'warning');
        return;
      }
      this.$confirm('此操作会删除你选中的书签分组, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 用户点击了确定按钮
        let deleteIndex;
        this.bookmarksGroup.forEach((item, index) => {
          if (item.groupName === group.groupName) {
            deleteIndex = index
          }
        });
        this.bookmarksGroup.splice(deleteIndex, 1);
        this.selectGroup = this.bookmarksGroup[0].groupName
        this.getGroupBookmarks()
        chrome.storage.local.set({bookmarksGroup: this.bookmarksGroup}, () => {
          console.log(group.groupName + '=>书签分组已删除')
          this.autoupload(true,0)
        })
      }).catch(() => {
        // 用户点击了取消按钮
        console.log('已取消删除书签分组');
      });


    },
    getGroupBookmarks() {
      this.groupBookmarks = this.bookmarksList.filter(item => item.group.groupName === this.selectGroup)
    },

    editBookmark(row) {
      this.bookmarkForm = {...row};
      this.dialogVisible = true
    },
    saveBookmark() {
      this.$refs['bookmarkForm'].validate(valid => {
        if (valid) {
          if (typeof this.bookmarkForm.group === 'string') {
            if (this.bookmarkForm.group.length > 5) {
              this.msg('', '分组名称不能超过5个字', 'warning');
              return;
            }
            let group = {
              id: Date.now(),
              groupName: this.bookmarkForm.group
            }
            this.bookmarkForm.group = group
            this.bookmarksGroup.push(group)
          }
          const index = this.bookmarksList.findIndex(item => item.id === this.bookmarkForm.id);
          this.bookmarksList.splice(index, 1)
          this.bookmarksList.push(this.bookmarkForm)
          chrome.storage.local.set({
            bookmarksGroup: this.bookmarksGroup,
            bookmarksList: this.bookmarksList
          }, () => {
            console.log(this.bookmarkForm.title + "=>书签更新成功");
            this.autoupload(this.autoAsync,this.asyncType)
          });
          this.selectGroup = this.bookmarkForm.group.groupName
          this.getGroupBookmarks()
          this.dialogVisible = false
        }
      });

    },
    deleteBookmark(row) {
      this.$confirm('你正在执行删除书签操作, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 用户点击了确定按钮
        const index = this.groupBookmarks.findIndex(item => item.url === row.url);
        this.groupBookmarks.splice(index, 1)
        const deleteIndex = this.bookmarksList.findIndex(item => item.url === row.url);
        if (deleteIndex !== -1) {
          this.bookmarksList.splice(deleteIndex, 1)
          chrome.storage.local.set({
            bookmarksGroup: this.bookmarksGroup,
            bookmarksList: this.bookmarksList
          }, () => {
            console.log(row.title + "=>书签删除成功");
            this.autoupload(true,0)
          });
        }
      }).catch(() => {
        // 用户点击了取消按钮
        console.log('已取消删除书签');
      });
    },
    /**
     * 将 arr1 合并到 arr2 中，如果 arr1 中的元素在 arr2 中存在，则覆盖
     * @param arr1
     * @param arr2
     * @param compareKey 判断相等的属性名
     */
    mergeAndDeduplicate(arr1, arr2, compareKey){
      arr1.forEach(item => {
        let index = arr2.findIndex(item2 => item2[compareKey] === item[compareKey]);
        if (index !== -1) {
          arr2[index] = item;
        } else {
          arr2.push(item);
        }
      });
      return arr2;
    },


  }
}
</script>

<style scoped>

#bookMarksSync {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  height: 550px;
}

#bookMarksSync ::v-deep .el-card__body {
  padding: 0;
}

.el-form-item {
  margin-bottom: 0;
}

#bookMarksSync ::v-deep .el-table--mini .el-table__cell {
  padding: 0;
}

#bookMarksSync ::v-deep .el-form-item__error {
  color: #f56c6c;
  font-size: 12px;
  line-height: 1;
  position: absolute;
  text-align: right;
  top: 65%;
  left: 0;
  width: 90%;
}

.bookmarksRow {
  padding: 0 !important;
}
</style>
